www.gusucode.com > vc++ 远程控制示例源程序-源码程序 > vc++ 远程控制示例源程序-源码程序\code\PeerYouC\SearchHostDlg.cpp

    // SearchHostDlg.cpp : implementation file
// Download by http://www.NewXing.com

#include "stdafx.h"
#include "PeerYouC.h"
#include "SearchHostDlg.h"
#include "Peersocket.h"
#include "command.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
HANDLE hThread;
HANDLE hThreadExit;
PARAM paa;
/////////////////////////////////////////////////////////////////////////////
// CSearchHostDlg dialog


CSearchHostDlg::CSearchHostDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CSearchHostDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CSearchHostDlg)
	//}}AFX_DATA_INIT
	bExit=false;
	bRealExit=false;
}


void CSearchHostDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CSearchHostDlg)
	DDX_Control(pDX, IDC_PROGRESS, m_Process);
	DDX_Control(pDX, IDC_LIST_HOST, m_listHosts);
	DDX_Control(pDX, IDC_IPADDRESS_SECOND, m_HostAddrSecond);
	DDX_Control(pDX, IDC_IPADDRESS_FIRST, m_HostAddrFirst);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CSearchHostDlg, CDialog)
	//{{AFX_MSG_MAP(CSearchHostDlg)
	ON_BN_CLICKED(IDC_EXIT, OnExit)
	ON_BN_CLICKED(IDC_SEARCH, OnSearch)
	ON_WM_CLOSE()
	ON_BN_CLICKED(IDC_STOP, OnStop)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CSearchHostDlg message handlers

void CSearchHostDlg::OnExit() 
{
	// TODO: Add your control notification handler code here
	if(bRealExit)
		SendMessage(WM_CLOSE);
	else
		MessageBox("需要先中止搜索");

}

BOOL CSearchHostDlg::OnInitDialog() 
{
	CDialog::OnInitDialog();
	
	// TODO: Add extra initialization here

	bExit=false;
	CRect rtClient;
	m_listHosts.GetClientRect(rtClient);
	LVCOLUMN colinfo;
	memset(&colinfo,0,sizeof(colinfo));
	colinfo.mask=LVCF_WIDTH|LVCF_FMT|LVCF_TEXT;
	colinfo.fmt=LVCFMT_CENTER;
	colinfo.cchTextMax=255;
	colinfo.cx=rtClient.Width()-40;
	colinfo.pszText="服务器地址";
	m_listHosts.InsertColumn(0,&colinfo);
	colinfo.cx=40;
	colinfo.pszText="状态";
	m_listHosts.InsertColumn(1,&colinfo);
	if(!CreateEvent(NULL,true,false,NULL))
		return false;
	ResetEvent(hThreadExit);
	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}

void CSearchHostDlg::OnSearch() 
{
	// TODO: Add your control notification handler code here
	CMainFrame* wMainFrame=(CMainFrame*)AfxGetApp()->GetMainWnd();
	CTreeCtrl& tree=wMainFrame->m_pTreeHost->GetTreeCtrl();
	if(!tree.DeleteAllItems())
		ASSERT(false);
	if(!m_listHosts.DeleteAllItems())
		ASSERT(false);
	CButton* button=(CButton*)GetDlgItem(IDC_SEARCH);
	if(button)
		button->EnableWindow(false);
	CStatic* sta=(CStatic*)GetDlgItem(IDC_MESSAGE);
	if(sta)
		sta->ShowWindow(SW_HIDE);
	/////////////////////////
	CString addrstart,addrend;
	m_HostAddrFirst.GetWindowText(addrstart);
	m_HostAddrSecond.GetWindowText(addrend);
	if(addrstart>addrend)
	{
		MessageBox("第二个地址应大于第一个地址");
		return ;
	}
	ULONG lStart=ntohl(inet_addr(addrstart));
	ULONG lEnd=ntohl(inet_addr(addrend));
	ULONG lSub=lEnd-lStart+1;	//一共有多少个地址
	m_Process.SetRange32(0,lSub);
	m_Process.ShowWindow(SW_SHOW);
	UINT ThreadID;
	HTREEITEM item=tree.InsertItem( "PeerYou服务器",0,0);
	paa.dlg=(void*)this;
	paa.count=lSub;
	paa.now=lStart;
	if((hThread=BeginThread(SearchFun,&paa,&ThreadID))<=0)
	{
		MessageBox("创建搜索线程失败");
		if(!tree.DeleteAllItems())
			ASSERT(false);
		return;
	}
	tree.Expand(item,TVE_EXPAND);
}

UINT WINAPI SearchFun(PVOID param)
{
	PARAM npa;
	memcpy(&npa,param,sizeof(PARAM));
	WSAEVENT event=WSACreateEvent();
	DWORD add;
	SOCKET sock;
	DWORD ret;
	int nhost=0;
	int index;
	CSearchHostDlg* dlg=(CSearchHostDlg*)npa.dlg;
	CMainFrame *mframe=(CMainFrame*)AfxGetApp()->GetMainWnd();
	CTreeCtrl& tree=mframe->m_pTreeHost->GetTreeCtrl();
	HTREEITEM item=tree.GetRootItem();
	HTREEITEM item2;
	SYSTEMINIT si;
	COMMAND com;
	char address[16];
	for(int i=0;i<npa.count;i++)
	{
		if(dlg->bExit)
		{
			dlg->bExit=false;
			closesocket(sock);
			WSACloseEvent(event);
			SetEvent(hThreadExit);
			return 0;
		}
		PeerCreateSocket(&sock,PEER_STREAM);
		add=npa.now+i;
		add=htonl(add);
		in_addr ina;
		memset(&ina,0,sizeof(ina));
		ina.S_un.S_addr=add;
		strcpy(address,inet_ntoa(ina));

		int TimeOut=6000; //设置发送超时6秒
		if(::setsockopt(sock,SOL_SOCKET,SO_SNDTIMEO,(char *)&TimeOut,sizeof(TimeOut))==SOCKET_ERROR)
		{
			::closesocket (sock);
			continue;
		}
		TimeOut=6000;//设置接收超时6秒
		if(::setsockopt(sock,SOL_SOCKET,SO_RCVTIMEO,(char *)&TimeOut,sizeof(TimeOut))==SOCKET_ERROR)
		{
			::closesocket (sock);
			continue;
		}
		//设置非阻塞方式连接
		unsigned long ul = 1;
		ret = ioctlsocket(sock, FIONBIO, (unsigned long*)&ul);
		if(ret==SOCKET_ERROR)
		{
			::closesocket (sock);
			continue;
		}

		PeerConnectSocket(sock,address,7788);
		//select 模型,即设置超时
		struct timeval timeout ;
		fd_set r;

		FD_ZERO(&r);
		FD_SET(sock, &r);
		timeout.tv_sec = 2; //连接超时15秒
		timeout.tv_usec =0;
		ret = select(0, 0, &r, 0, &timeout);
		if ( ret >0 )
		{
			//一般非锁定模式套接比较难控制,可以根据实际情况考虑 再设回阻塞模式
			unsigned long ul1= 0 ;
			ret = ioctlsocket(sock, FIONBIO, (unsigned long*)&ul1);
			if(ret==SOCKET_ERROR){
			::closesocket (sock);
			continue;
			}

			index=dlg->m_listHosts.InsertItem(dlg->m_listHosts.GetItemCount(),address);
			dlg->m_listHosts.SetItemText(index,1,"在线");
			item2=tree.InsertItem(address,1,1,item);
			memset(&com,0,sizeof(com));
			com.CommandID=PEER_SYSTEM_INIT;
			com.DataSize=0;
			if(PeerSendDataS(sock,(char*)&com,sizeof(com),&ret,event)&&ret==sizeof(com))
			{
				if(PeerRecvDataS(sock,(char*)&si,sizeof(si),&ret,event)&&ret==sizeof(si))
				{
					tree.InsertItem(si.computer,2,2,item2);
					tree.InsertItem(si.user,3,3,item2);
					tree.InsertItem(si.os,4,4,item2);
					tree.InsertItem(si.processor,5,5,item2);
					tree.InsertItem(si.mem,6,6,item2);
					tree.InsertItem(si.disk,7,7,item2);
				}
			}

			tree.RedrawWindow();
			nhost++;
		}
		else
		{
			index=dlg->m_listHosts.InsertItem(dlg->m_listHosts.GetItemCount(),address);
			dlg->m_listHosts.SetItemText(index,1,"未通");
		}
		dlg->m_Process.SetPos(i+1);
		closesocket(sock);
	}
	WSACloseEvent(event);
	dlg->m_Process.ShowWindow(SW_HIDE);
	CButton* button=(CButton*)dlg->GetDlgItem(IDC_SEARCH);
	if(button)
		button->EnableWindow(true);
	CStatic* sta=(CStatic*)dlg->GetDlgItem(IDC_MESSAGE);
	if(sta)
	{
		sta->ShowWindow(SW_SHOW);
		char msg[100];
		sprintf(msg,"查找已经完成,%d个主机在线!",nhost);
		sta->SetWindowText(msg);
	}
	if(nhost==0)
		tree.DeleteAllItems();
	dlg->bExit=false;
	return 0;
}

void CSearchHostDlg::OnClose() 
{
	// TODO: Add your message handler code here and/or call default
	CDialog::OnClose();
}

void CSearchHostDlg::OnStop() 
{
	// TODO: Add your control notification handler code here
	UpdateData();
	bExit=true;
	bRealExit=true;
	DWORD n = WaitForSingleObject(hThreadExit,60000);
	Sleep(500);
	if(n==WAIT_TIMEOUT)
	{
		TerminateThread(hThread,0);
	}
	CloseHandle(hThreadExit);
	CloseHandle(hThread);
	CStatic* sta=(CStatic*)GetDlgItem(IDC_MESSAGE);
	m_Process.ShowWindow(SW_HIDE);
	CButton* button=(CButton*)GetDlgItem(IDC_SEARCH);
	button->EnableWindow();
	if(sta)
	{
		sta->ShowWindow(SW_SHOW);
		sta->SetWindowText("中止搜索主机!");
	}
	
}